﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using ENG.EngStartQueueLib;
using System.Diagnostics;

namespace ENG.EngStartQueue
{
  public partial class FrmExec : Form
  {
    private const int IMG_WAIT = 0;
    private const int IMG_RUN = 1;
    private const int IMG_OK = 2;
    private const int IMG_ERROR = 3;

    bool isSimulation;
    public bool IsSimulation
    {
      set
      {
        isSimulation = value;
      }
    }
    bool isPaused = false;
    QueueSett q = null;
    PerformanceMeter pmDisc = null;
    PerformanceMeter pmProc = null;

    public FrmExec()
    {
      InitializeComponent();
    }

    private void FrmExec_Load(object sender, EventArgs e)
    {
      Init();

      if (Program.LibSett.StartMinimized)
        this.WindowState = FormWindowState.Minimized;

      this.Show();

      if (Program.LibSett.StartMinimized)
        this.WindowState = FormWindowState.Minimized;

      Go();
    }

    int lastExecIndex = 0;
    int okMax = Program.LibSett.OkExecCycles;
    int okCount = 0;
    private void Go()
    {
      while (true)
      {
        CheckForOk();
        if ((okCount >= okMax) && (!isPaused))
        {
          okCount = 0;

          if (!ExecuteNext())
            break;
        }
        Application.DoEvents();
        System.Threading.Thread.Sleep(250);
        Application.DoEvents();
        System.Threading.Thread.Sleep(250);
        Application.DoEvents();
        System.Threading.Thread.Sleep(250);
        Application.DoEvents();
      }

      this.Text = "Exec done...";

      if (txtErr.Text.Length == 0)
        Application.Exit();

      btnStartManager.Visible = true;
    }

    private bool ExecuteNext()
    {

      if (q.Items.Count == 0)
        return false;

      if (lastExecIndex > q.Items.Count - 1)
      {
        // zmena obrazku posledni spustene aplikace na "OK", pokud je "RUN", tj pokud nebyla "ERROR"
        if (lvwItems.Items[lastExecIndex - 1].ImageIndex == IMG_RUN)
          lvwItems.Items[lastExecIndex - 1].ImageIndex = IMG_OK;
        return false;
      }

      if (lastExecIndex > 0)
        if (lvwItems.Items[lastExecIndex-1].ImageIndex != IMG_ERROR)
          lvwItems.Items[lastExecIndex-1].ImageIndex = IMG_OK;

      lvwItems.Items[lastExecIndex].ImageIndex = IMG_RUN;
      AdjustForVisible(lastExecIndex);
      Application.DoEvents();

      ExecInfo ei = q.Items[lastExecIndex];

      ProcessStartInfo psi = new ProcessStartInfo();
      psi.Arguments = ei.Arguments;
      psi.FileName = ei.FullPath;
      psi.WindowStyle = ei.WindowStyle;
      psi.WorkingDirectory = ei.WorkingDirectory;

      Process p = new Process();
      p.StartInfo = psi;

      try
      {
        if (!isSimulation)
        {
          if (ei.IsActive)
          {
            p.Start();
            p.PriorityClass = ei.Priority;
          }

        }

        this.Text = string.Format(
          "Exec [{0}/{1}] {2}",
          lastExecIndex + 1,
          q.Items.Count,
          q.Items[lastExecIndex].FileName);

      }
      catch (Exception ex)
      {
        txtErr.Text =
          txtErr.Text + 
          lvwItems.Items[lastExecIndex].Text + "==>" +
          ex.Message + " (" +
          lvwItems.Items[lastExecIndex].ToolTipText + ")" + Environment.NewLine;
        lvwItems.Items[lastExecIndex].ImageIndex = IMG_ERROR;
      }
      Application.DoEvents();

      lastExecIndex += 1;

      return true;
    }

    private void AdjustForVisible(int lastExecIndex)
    {
      int ind = lastExecIndex + 1;
      if (ind >= lvwItems.Items.Count)
        ind = lvwItems.Items.Count - 1;

      lvwItems.Items[ind].EnsureVisible();
    }

    private void CheckForOk()
    {
      bool result; 
      double p;
      bool o;
      pmDisc.GetInfo(out p, out o);
      UpdateProgress(prgDisc, p);
      result = o;

      pmProc.GetInfo(out p, out o);
      UpdateProgress(prgProc, p);
      result = o & result;

      if (result)
        okCount++;
      else if (okCount > 0)
        okCount--;
    }

    private void UpdateProgress(ESystem.Forms.EProgressBar prg, double p)
    {
      int ip = (int)(p * 100);
      ip = 100 - ip;
      if (prg.Maximum < ip)
        prg.Maximum = ip;
      if (prg.Minimum > ip)
        prg.Minimum = ip;

      prg.Value = ip;
    }

    private void Init()
    {
      q = QueueSett.Load(Program.QueueFile);

      foreach (var fItem in q.Items)
      {
        ListViewItem ni = new ListViewItem();
        ni.Text = fItem.FileName;
        ni.ToolTipText = fItem.FullPath;
        ni.ImageIndex = IMG_WAIT;

        lvwItems.Items.Add(ni);
      } // foreach (var fItem in q.Items)

      Program.LoadPerformanceMeters(out pmDisc, out pmProc);


    }

    private void btnContinue_Click(object sender, EventArgs e)
    {
      isPaused = false;
      okCount = 0;
      btnPause.Visible = true;
      btnContinue.Visible = false;
    }

    private void btnPause_Click(object sender, EventArgs e)
    {
      isPaused = true;
      btnContinue.Visible = true;
      btnPause.Visible = false;
    }

    private void btnStartManager_Click(object sender, EventArgs e)
    {
      Process p = new Process();
      p.StartInfo = new ProcessStartInfo(
        Application.ExecutablePath);

      p.Start();
      Application.Exit();
    }
  }
}
